package com.snap.vseries.logger;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.orhanobut.logger.LogStrategy;
import com.snap.vseries.MoleApplication;
import com.snap.vseries.utils.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

/**
 * msg中含有"exp begin"为开始
 * 含有"exp end"为结束
 * 记录一个文件
 */
public class ExpLogStrategy implements LogStrategy {
    private static final String NEW_LINE = System.getProperty("line.separator");
    @NonNull
    private final Handler handler;

    ExpLogStrategy(@NonNull Handler handler) {
        this.handler = Utils.checkNotNull(handler);
    }

    @Override
    public void log(int level, @Nullable String tag, @NonNull String message) {
        Utils.checkNotNull(message);
        handler.sendMessage(handler.obtainMessage(level, message));
    }

    static class WriteHandler extends Handler {

        private final String folder;
        private HashMap<String, OutputStreamWriter> fileWriters = new HashMap<>();
        private HashMap<String, File> logFiles = new HashMap<>();


        WriteHandler(@NonNull Looper looper, @NonNull String folder) {
            super(Utils.checkNotNull(looper));
            this.folder = Utils.checkNotNull(folder);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            String[] array = ((String) msg.obj).split("\\|");
            if (array.length == 2) {
                String expName = array[1].trim();
                String content = array[0] + NEW_LINE;
                if (content.contains("exp begin")) {
                    beginLog(content, expName);
                } else if (content.contains("exp end")) {
                    endLog(content, expName);
                } else {
                    log(content, expName);
                }
            }
        }

        private void beginLog(String content, String expName) {
            closeWriter(expName);
            // TODO: 2020/3/4 文件名称
            File logFile = getLogFile(folder, expName);
            logFiles.put(expName, logFile);
            try {
                FileOutputStream fos = new FileOutputStream(logFile, true);
                OutputStreamWriter fileWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
                fileWriters.put(expName, fileWriter);
            } catch (IOException e) {
                e.printStackTrace();
            }
            log(content, expName);
        }

        private void log(String content, String expName) {
            OutputStreamWriter fileWriter = fileWriters.get(expName);
            if (fileWriter == null) return;
            try {
                fileWriter.append(content);
                fileWriter.flush();
            } catch (IOException e) {
            }
        }

        private void endLog(String content, String expName) {
            log(content, expName);
            closeWriter(expName);
        }

        private void closeWriter(String expName) {
            OutputStreamWriter fileWriter = fileWriters.get(expName);
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    if (fileWriter != null) {
                        try {
                            fileWriter.flush();
                            fileWriter.close();
                        } catch (IOException e1) { /* fail silently */ }
                    }
                } finally {
                    fileWriters.remove(expName);
                }
            }
            if (logFiles.get(expName) != null) {
                FileUtils.ensureWriteFile(logFiles.get(expName));
                logFiles.remove(expName);
            }
        }

        private File getLogFile(@NonNull String folderName, @NonNull String fileName) {
            Utils.checkNotNull(folderName);
            Utils.checkNotNull(fileName);

            File folder = new File(folderName);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            return new File(folder, String.format("%s.txt", fileName));
        }
    }
}
